#	Plugin interface
#		methods: search, search_by_ref, init, title, version, desc
#
#
#
#	Grabber plugin
#		The Movie Db
#
#		
#

package grabbers::tmdb;

use modules::MythTV;
use HTML::Parser;
use HTML::TreeBuilder;
use HTML::Entities;
use LWP::Simple;
use LWP::UserAgent;
use Getopt::Long;
use File::Spec;
use Text::Levenshtein qw(distance);

# My api key (not yours)
our $myapikey = "b1a8d9cc6920961b0906b15e57fe36a2";
our $base_url =  "http://image.tmdb.org/t/p/";
our $backdrop_size = "w1280";
our $poster_size = "w500";
our $still_size = "w300";
our $debug = 0;


my $_rev = '$Rev: 166 $';

# Exports
our $VERSION = "3.0";
sub title
{
	return "The Move Db";
}
sub desc
{
	return "Search on www.themoviedb.org";
}
sub version
{
	$_rev =~ s/\$//g;
	return $VERSION.", ".$_rev ;
}
#end Exports


sub search 
{
	my $self = shift;
	my $title = shift;
	my $subtitle = shift;
	my $season = shift;
	my $episode = shift;
	my %details;	
	my $result = 0;
	if( $season == 0  && $episode == 0 )
	{
		$result = get_show(\%details, $title, $subtitle, $season, $episode, 0);
	}

	if($result >0)
	{
		getData(\%details, $result);
	}

	return %details;
}

sub search_by_ref
{
	my $ref = shift;
	my $details;	
	return $details;
}

sub init
{
}

sub new
{
    my($class, %args) = @_;
    my $self = bless({}, $class);
    
    init();
    
    return $self;
}
#######################################
##   UTILITIES
#######################################
#conduct a quick search on TvRage.com
sub get_show {
	my $file_details = shift;
	my $title = shift;
	my $subtitle = shift;
	my $season = shift;
	my $episode = shift;
	my $year = shift;
		
	my $result=0;
	my $Search;
	if( $year != 0 )
	{
		$Search = $title."_".$year;
	}
	else
	{
		$Search = $title;
	}
	my $se_ep = $season."x".$episode;
	if ( $title ne "" )
	{
		my $url = "https://api.themoviedb.org/3/search/movie?api_key=".$myapikey."&query=".$Search;
		if($debug)
		{
			print $url."\n";
		}
		my $site = LWP::Simple::get($url);
		if(!(defined($site)))
		{
			print "The Movie Db lookup failed, trying again in 5 seconds...\n";
			sleep(5);
			$site = LWP::Simple::get($url);
		}
		if(!(defined($site)))
		{
			print "The Movie Db lookup failed: ".$Search."\n";
			return;
		}
		if($debug)
		{
			print "Initial Query:".$site."\n";
		}
		($results_data) = $site =~ m/"results":\[(.*?)\]/;
		if($debug)
		{
			print "Results data:".$results_data."\n";
		}
		my %entry_score;
		$entry_score{title}="";
		$entry_score{ref} =0;
		$best_score = 100;
		$best_ref=0;
		foreach $entry ( $results_data =~ m/({.*?})/g )
		{
			parse_json($entry,\&handle_search,\%entry_score);

			$errors = scoreMatch($Search, $entry_score{title});
			if($errors < $best_score)
			{
				$best_score = $errors;
				$best_ref = $entry_score{ref};
				printf "  Found better match: ".$entry_score{title}."\n";
			}
		}
		$result = $best_ref;
	}
	return $result;
}
sub scoreMatch
{
	my $first = shift;
	my $second = shift;
	$first =~ s/[^\w\s]//g;
	$second =~ s/[^\w\s]//g;
	my $errors = distance(lc($first), lc($second));
#	print " Errors between \"$first\" and \"$second\": $errors\r\n";
	return $errors;
}

sub handle_search
{
	my $section = shift;
	my $value = shift;
	my $id = shift;
	if( $section eq 'original_title' )
	{
		$id->{title} = $value;
	}
	elsif( $section eq 'id' )
	{
		$id->{ref} = $value;
	}
}


sub getData {
	my $file_details = shift(@_);
	my $ref = shift;
	
	my $url = "https://api.themoviedb.org/3/movie/".$ref."?api_key=".$myapikey."&append_to_response=credits,releases";
	if($debug)
	{
		print $url."\n";
	}
	my $site = LWP::Simple::get($url);
	if(!(defined($site)))
	{
		print "The Movie Db lookup failed, trying again in 5 seconds...\n";
		sleep(5);
		$site = LWP::Simple::get($url);
	}
	if(!(defined($site)))
	{
		print "The Movie Db lookup failed: ".$Search."\n";
	}
	parse_json($site,\&handle_main,$file_details);
}

sub parse_json
{
	my $data=shift;
	my $handler=shift;
	my $context = shift;

	my $sec;
	my $val;
	if($debug)
	{
		print "Parsing Chunk\n";
	}
	foreach $element ( $data =~ m/(.+?":(?:\{[^\}]+?\}|\{".+?":\[.+?\]\}|\[[^\]]+?\]|.+?))(?:,"|})/g )
	{
		if($debug)
		{
			print "Getting Details:".$element."\n";
		}
		my ($sec,$val) = $element =~ m/(.*?):(.*)/;
		# Clean up the data
		$sec =~ s/^,?\[?{?"//;
		$sec =~ s/"$//;
		$val =~ s/^"//;
		$val =~ s/"$//;
		if($debug)
		{
			print "    ".$sec."->".$val."\n";
		}
		$handler->($sec,$val,$context);
	}
	if($debug)
	{
		print "Finished Chunk\n\n";
	}

}

sub handle_main
{
	my $section = shift;
	my $value = shift;
	my $file_details = shift;
	if ($section eq 'title' )
	{
		$file_details->{Title} = $value;
	}
	elsif ($section eq 'runtime' )
	{
		$file_details->{Length} = $value;
	}
	elsif ($section eq 'overview' )
	{
		$file_details->{Plot} = $value;
	}
	elsif ($section eq 'release_date' )
	{
		($file_details->{Year}) = $value =~ m/^(\d\d\d\d)-.*/;
	}
	elsif ($section eq 'id' )
	{
		$result = $value;
	}
	elsif ($section eq 'backdrop_path' )
	{
		$file_details->{FanartUrl} = $base_url.$backdrop_size.$value;
	}
	elsif ($section eq 'poster_path' )
	{
		$file_details->{PosterUrl} = $base_url.$poster_size.$value;
	}
	elsif ($section eq 'production_companies' )
	{
		parse_json($value,\&handle_credits,$file_details);
	}
	elsif ($section eq 'credits' )
	{
		parse_json($value,\&handle_credits,$file_details);
	}
	elsif ($section eq 'releases' )
	{
		($country_data) = $value =~ m/({[^{]*?"iso_3166_1":"US".*?})/;
		parse_json($country_data,\&handle_releases,$file_details);
	}
}

sub handle_credits
{
	my $section = shift;
	my $value = shift;
	my $file_details = shift;
	if ($section eq 'cast' )
	{
		parse_json($value,\&handle_cast,$file_details);
	}
	elsif ($section eq 'crew' )
	{
		($director_data) = $value =~ m/({.*?"job":"Director".*?})/;
		parse_json($director_data,\&handle_crew,$file_details);
	}
}

sub handle_cast
{
	my $section = shift;
	my $value = shift;
	my $file_details = shift;
	if ($section eq 'name' )
	{
		if(!defined $file_details->{Cast})
		{
			$file_details->{Cast}= $value;
		}
		else
		{
			$file_details->{Cast} = $file_details->{Cast}.",".$value;
		}
	}
}

sub handle_crew
{
	my $section = shift;
	my $value = shift;
	my $file_details = shift;
	if ($section eq 'name' )
	{
		$file_details->{Director} = $value;
	}
}
sub handle_releases
{
	my $section = shift;
	my $value = shift;
	my $file_details = shift;
	if ($section eq 'certification' )
	{
		$file_details->{Rating} = $value;
	}
}

sub comparestrings
{
	my $first = shift;
	my $second = shift;
	my $likeness;
	# make the comparison a little easier by removing
	# qutoes commas etc, plus make both string upper case.
	# Convert single digits to words
	$first = digit2str($first);	
	$second = digit2str($second);	
	$first = uc($first);
	$second = uc($second);
	$first =~ s/[^\w\s]//g;
	$second =~ s/[^\w\s]//g;
	$leven_distance = distance($first, $second);
	my $totallen = length($first) + length($second);
	return (($totallen - $leven_distance) / $totallen) * 100;
}

sub digit2str
{
	my $phrase = shift;
	$phrase =~ s/\D1\D/one/g; 
	$phrase =~ s/\D2\D/two/g; 
	$phrase =~ s/\D3\D/three/g; 
	$phrase =~ s/\D4\D/four/g; 
	$phrase =~ s/\D5\D/five/g;
	$phrase =~ s/\D6\D/six/g; 
	$phrase =~ s/\D7\D/seven/g; 
	$phrase =~ s/\D8\D/eight/g; 
	$phrase =~ s/\D9\D/nine/g; 
	$phrase =~ s/\D10\D/ten/g; 
	return $phrase;
}

1;
